
from flask import Flask, Response
import threading
import time
import logging
import cv2


import carController

app = Flask(__name__)



# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)


def generate_frames():
    cap = cv2.VideoCapture('../video/4.mp4')

    while True:
        success, frame = cap.read()
        if not success:
            break
        else:
            result = carController.detect_objects(frame)
            ret, buffer = cv2.imencode('.jpg', result)
            frame = buffer.tobytes()
            # 使用multipart/x-mixed-replace格式返回视频流
            yield (b'--frame\r\n'
                   b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
    cap.release()

@app.route('/video_feed')
def video_feed():
    # 返回视频流响应
    return Response(generate_frames(),
                    mimetype='multipart/x-mixed-replace; boundary=frame')


@app.route('/')
def index():
    # 返回包含视频流的HTML页面
    return """
    <html>
    <head>
        <title>视频流演示</title>
    </head>
    <body>
        <h1>实时视频流</h1>
        <img src="/video_feed" width="640" height="480">
    </body>
    </html>
    """



if __name__ == '__main__':

    
    # 先启动 Flask 服务器
    # app.run(host='0.0.0.0', port=6858, debug=True)
    # 1. 启动Flask服务器（放到子线程，非阻塞）
    flask_thread = threading.Thread(
        target=lambda: app.run(host='0.0.0.0', port=6858, debug=True, use_reloader=False)
    )
    flask_thread.daemon = True  # 主线程结束时，子线程自动退出
    flask_thread.start()


    # 创建实例时，只需传 server_url（必要参数）和可选的 username
    # client = connitSocket.RobustDeviceWebSocketClient(
    #     server_url="ws://192.168.3.54:3570/ruoyi-vue-service",  # 必传参数
    #     username="car"  # 可选参数，默认是 "robust_device"
    # )
    server_url = "ws://192.168.3.54:3570/ruoyi-vue-service"
    client = carController.RobustDeviceWebSocketClient(server_url,username="car")
    # 正确启动WebSocket线程，设置为daemon以避免阻止程序退出
    socket_thread = threading.Thread(target=client.start)
    socket_thread.daemon = True  # 设置为守护线程，确保主线程退出时能正确清理
    socket_thread.start()
    
    logger.info("服务器已启动，按Ctrl+C退出")
    
    # 保持主线程活跃，避免解释器过早关闭
    try:
        while True:
            time.sleep(1)  # 主线程休眠，定期检查
            # 检查子线程是否还在运行
            if not flask_thread.is_alive() and not socket_thread.is_alive():
                logger.info("所有子线程已结束，程序退出")
                break

    except KeyboardInterrupt:
        logger.info("接收到中断信号，程序准备退出")
    finally:
        logger.info("程序正在退出...")

